﻿using UnityEngine;
using System.Collections;

public class CameraMove3D : MonoBehaviour
{
    [SerializeField]
    private float planeSpeed = 2.0f;
    [SerializeField]
    private float MouseWheelFactor = 10.0f;
    [SerializeField]
    private float RotationSpeed = 60.0f;
    [SerializeField]
    private float RotationDistance = 20.0f;

    private float hor;
    private float ver;
    private float upDown;
    private float MouseWheel;

    private float MouseXDelta;
    private float MouseYDelta;

    /// <summary>
    /// The camera motion per frame relative to the world
    /// </summary>
    private Vector3 m_MotionChange_World;
    /// <summary>
    /// The camera motion per frame relative to the self
    /// </summary>
    private Vector3 m_MotionChange_Self;

    /// <summary>
    /// The point where the camera is rotation around while RMB is held down
    /// </summary>
    private Vector3 m_rotationPoint;

    void Start()
    {
        //Debug.Log(VoxelTerrain.Instance);
    }

    // Update is called once per frame
    void Update()
    {
        DebugStuff();

        // Resetting motion vectors
        m_MotionChange_World = m_MotionChange_Self = Vector3.zero;

        // Moving it along the axes
        hor = Input.GetAxis("Horizontal");
        ver = Input.GetAxis("Vertical");
        upDown = Input.GetAxis("UpDown");
        MouseWheel = Input.GetAxis("Mouse ScrollWheel");

        Vector3 CrossForward = Vector3.Cross(transform.right, Vector3.up);

        m_MotionChange_World += (transform.right * hor + Vector3.up * upDown + CrossForward * ver) * planeSpeed;

        if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && MouseWheel != 0)
        {
            VoxelTerrain.RenderHeight = Mathf.Clamp(MouseWheel > 0 ? VoxelTerrain.RenderHeight + 1 : VoxelTerrain.RenderHeight - 1, VoxelTerrain.LayerRenderAmount, VoxelTerrain.WORLD_HEIGHT >> 4 - VoxelTerrain.LayerRenderAmount);
        }
        else
        {
            m_MotionChange_Self += new Vector3(0.0f, 0.0f, MouseWheel * MouseWheelFactor) * planeSpeed;
        }

        // Changing rotation
        if (Input.GetMouseButton(2))
        {
            MouseXDelta = Input.GetAxis("Mouse X");
            MouseYDelta = Input.GetAxis("Mouse Y");

            m_rotationPoint = Camera.main.transform.position + Camera.main.transform.forward * RotationDistance;

            transform.RotateAround(m_rotationPoint, transform.right, -MouseYDelta * RotationSpeed * Time.deltaTime);
            transform.RotateAround(m_rotationPoint, Vector3.up, MouseXDelta * RotationSpeed * Time.deltaTime);

            // Clamp position
            while (Vector3.Dot(CrossForward, transform.forward) < 0)
            {
                transform.RotateAround(m_rotationPoint, transform.right, MouseYDelta * RotationSpeed);
            }
        }

        if (Input.GetMouseButtonUp(1))
        {
            // Resetting
            m_rotationPoint = new Vector3(0, -100, 0);
        }

        // Translating the camera with the motion vectors
        transform.Translate(m_MotionChange_World * Time.deltaTime, Space.World);
        transform.Translate(m_MotionChange_Self * Time.deltaTime, Space.Self);
    }

    private void DebugStuff()
    {
        float dist;
        Plane plane = new Plane(Vector3.up, Vector3.zero);
        plane.Raycast(new Ray(Camera.main.transform.position, Camera.main.transform.forward), out dist);

        //Debug.Log(dist);
    }
}
